from flask import Blueprint, request, jsonify
from sparkai.llm.llm import ChatSparkLLM, ChunkPrintHandler
from sparkai.core.messages import ChatMessage
import hmac
import hashlib
import base64
from datetime import datetime
from email.utils import formatdate
from functools import lru_cache
import logging
from exts import csrf

bp = Blueprint('answer', __name__, url_prefix='/')

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 加密
SECRET_KEY = "<tyghyhujfrdsxcv@jhyhft"

# 星火认知大模型配置（Spark Lite）
SPARKAI_URL = 'wss://spark-api.xf-yun.com/v1.1/chat'
SPARKAI_APP_ID = '23a35a2a'
SPARKAI_API_SECRET = 'ODFlOTc4ODI4MGY5NGE1ZTY5YTA1M2Vj'
SPARKAI_API_KEY = '4205f415faa1f117079e32014f9bc101'
SPARKAI_DOMAIN = 'lite'

# 增强版系统提示词
SYSTEM_PROMPT = """
你是一个专业的电商平台AI助手，专门帮助分析用户行为数据、提供商品推荐建议和解答电商相关问题。
请遵循以下规则：
1. 回答要专业、简洁、有帮助，针对电商场景提供实用建议
2. 对于数据分析类问题，结合数据特征提供具体可行的优化建议
3. 对于不确定的问题，不要编造信息，明确告知用户你不知道
4. 回答使用中文，除非用户特别要求其他语言
5. 保持友好和乐于助人的态度
6. 对于专业术语，提供简单易懂的解释
7. 对于数据查询结果，帮助解读数据含义和业务价值
8. 提供建议时考虑实际可操作性

电商专业知识：
- 常见用户行为类型：浏览(pv)、加购(cart)、收藏(fav)、购买(buy)
- 关键指标：转化率、跳出率、复购率、客单价
- 常用分析方法：漏斗分析、路径分析、RFM模型

回答格式要求：
1. 重要数据使用**加粗**强调
2. 分步骤建议使用数字列表
3. 复杂概念用简单例子说明
"""

# 常见问题预设回答模板
COMMON_QUESTIONS = {
    "如何提高转化率": "提高转化率可以从以下几个方面入手:\n\n1. **优化商品页面**: 确保商品图片清晰、描述详细\n2. **简化购买流程**: 减少结算步骤\n3. **提供优惠激励**: 如限时折扣、满减活动\n4. **增强信任元素**: 客户评价、销量展示\n5. **优化移动端体验**: 确保移动设备上操作流畅",
    "热门商品有哪些": "您可以通过以下方式获取热门商品信息:\n\n1. 查看'数据可视化'页面中的'热门商品点击排行'\n2. 分析'商品购买转化率'报表\n3. 关注'用户行为分析'中的商品排行\n\n需要我为您查询具体数据吗?",
    "用户行为分析": "用户行为分析主要包括:\n\n1. **行为类型**: 浏览、加购、收藏、购买\n2. **分析维度**:\n   - 时间分布(天/小时)\n   - 商品/类目分布\n   - 用户分群\n3. **关键指标**:\n   - 转化率\n   - 用户路径\n   - 复购率\n\n您想了解哪方面的具体分析?"
}


def generate_hmac_signature(api_secret, date, request_line):
    """生成 HMAC-SHA256 签名"""
    signature_origin = f"host: spark-api.xf-yun.com\ndate: {date}\n{request_line}"
    signature_sha = hmac.new(api_secret.encode('utf-8'), signature_origin.encode('utf-8'), hashlib.sha256).digest()
    signature = base64.b64encode(signature_sha).decode('utf-8')
    return signature


def generate_authorization(api_key, signature):
    """生成 Authorization 头"""
    return f'api_key="{api_key}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature}"'


@lru_cache(maxsize=100)
def get_cached_answer(question):
    """缓存常见问题的回答"""
    return COMMON_QUESTIONS.get(question, None)


@bp.route('/get_answer', methods=['POST'])
@csrf.exempt  # 仅为这个路由禁用CSRF
def get_answer():
    user_input = request.json.get('question', '').strip()

    if not user_input:
        return jsonify({'answer': '请提供有效的问题内容。'})

    # 检查是否是常见问题
    cached_answer = get_cached_answer(user_input)
    if cached_answer:
        return jsonify({'answer': cached_answer})

    try:
        # 生成时间戳（RFC1123 格式）
        date = formatdate(timeval=None, localtime=False, usegmt=True)
        # 生成请求行
        request_line = "POST /v1.1/chat HTTP/1.1"
        # 生成 HMAC 签名
        signature = generate_hmac_signature(SPARKAI_API_SECRET, date, request_line)
        # 生成 Authorization 头
        authorization = generate_authorization(SPARKAI_API_KEY, signature)

        # 初始化星火认知大模型
        spark = ChatSparkLLM(
            spark_api_url=SPARKAI_URL,
            spark_app_id=SPARKAI_APP_ID,
            spark_api_key=SPARKAI_API_KEY,
            spark_api_secret=SPARKAI_API_SECRET,
            spark_llm_domain=SPARKAI_DOMAIN,
            streaming=False,
            temperature=0.3,  # 降低随机性，使回答更稳定
            max_tokens=1024  # 增加最大token数以获得更完整回答
        )

        # 构造消息 - 添加系统提示和用户问题
        messages = [
            ChatMessage(
                role="system",
                content=SYSTEM_PROMPT
            ),
            ChatMessage(
                role="user",
                content=user_input
            )
        ]

        # 调用星火认知大模型
        handler = ChunkPrintHandler()
        response = spark.generate([messages], callbacks=[handler])

        # 提取 AI 的回答
        answer = response.generations[0][0].text

        # 对回答进行后处理
        answer = postprocess_answer(answer)

        return jsonify({'answer': answer})

    except Exception as e:
        logger.error(f"Error processing question: {user_input}, Error: {str(e)}", exc_info=True)
        error_message = "抱歉，处理您的请求时出现了问题，请稍后再试。"
        if "AppIdNoAuthError" in str(e):
            error_message = "服务认证失败，请稍后再试。"
        elif "RateLimit" in str(e):
            error_message = "当前请求过多，请稍后再试。"
        return jsonify({'answer': error_message, 'error': str(e)})


def postprocess_answer(answer):
    """对AI回答进行后处理"""
    # 移除可能的多余前缀
    if answer.startswith("回答：") or answer.startswith("Answer:"):
        answer = answer[answer.find(":") + 1:].strip()

    # 确保回答不以换行符开头
    answer = answer.lstrip('\n')

    # 格式化Markdown样式为HTML
    answer = answer.replace("**", "<strong>").replace("**", "</strong>")

    # 限制回答长度
    max_length = 1500
    if len(answer) > max_length:
        answer = answer[:max_length] + "...(回答过长，已截断)"

    return answer